package com.mangofactory.flapper.parsley.lifecycle
{
	import com.mangofactory.aop.aspects.Aspect;
	import com.mangofactory.aop.configuration.AspectContainer;
	import com.mangofactory.aop.configuration.AspectContainerBuilder;
	import com.mangofactory.aop.configuration.ClassProxyDefinition;
	import com.mangofactory.aop.configuration.ClassRegistry;
	import com.mangofactory.aop.configuration.ExplicitClassRegistry;
	import com.mangofactory.aop.configuration.MethodProxyDefinition;
	import com.mangofactory.aop.configuration.ProxyPolicy;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import mx.core.FlexGlobals;
	
	import org.as3commons.bytecode.proxy.ClassProxyInfo;
	import org.as3commons.bytecode.proxy.ProxyFactory;
	import org.as3commons.bytecode.reflect.ByteCodeType;
	import org.spicefactory.parsley.core.builder.AsyncConfigurationProcessor;
	import org.spicefactory.parsley.core.registry.ObjectDefinition;
	import org.spicefactory.parsley.core.registry.ObjectDefinitionRegistry;
	
	public class ProxyGeneratorConfigurationProcessor extends EventDispatcher implements AsyncConfigurationProcessor
	{
		private var builder:AspectContainerBuilder

		public function ProxyGeneratorConfigurationProcessor(aspectContainerBuilder:AspectContainerBuilder)
		{
			this.builder = aspectContainerBuilder;
		}
		
		public function cancel():void
		{
		}
		
		public function processConfiguration(registry:ObjectDefinitionRegistry):void
		{
			var instantiator:ProxyInstantiator = new ProxyInstantiator(builder.proxyFactory);
			var ids:Array = registry.getDefinitionIds();
			for each (var objectId:String in ids)
			{
				var definition:ObjectDefinition = registry.getDefinition(objectId);
				var clazz:Class = definition.type.getClass();
				if (builder.requiresProxy(clazz))
				{
					builder.addClass(clazz);
					definition.instantiator = instantiator;
				}
			}
			var aspectContainer:AspectContainer = builder.build();
			aspectContainer.addEventListener(Event.COMPLETE,onComplete);
		}

		private function onComplete(event:Event):void
		{
			dispatchEvent(new Event(Event.COMPLETE));
		}
	}
}
